home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48_2 / chasm01.sha / link.c < prev    next >
C/C++ Source or Header  |  1995-03-23  |  8KB  |  523 lines

  1. /*
  2.  *    link.c - linked list routines
  3.  *
  4.  *    @(#)link.c    1.1 91/04/10
  5.  *
  6.  *    Copyright (c) 1991 Steve Scherf
  7.  *
  8.  *    Author:    Steve Scherf
  9.  *    Date:    Wed Apr 10 22:53:11 PDT 1991
  10.  *
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include "chasm.h"
  15.  
  16. #define T_INST    0    /* instruction type link */
  17. #define T_CON    1    /* constant type link */
  18. #define T_STR    2    /* string type link */
  19. #define T_PAD    3    /* pad type link */
  20.  
  21.  
  22. struct link {
  23.     struct link *l_next;
  24.     int l_type;
  25.     int l_n;
  26.     union {
  27.         struct {
  28.             char *l_l;
  29.             int l_v;
  30.             int l_va;
  31.         } l;
  32.         struct {
  33.             int l_i[4];
  34.             int l_s[3];
  35.         } i;
  36.         struct {
  37.             struct link *l_c;
  38.             int l_con;
  39.             unsigned char *l_s;
  40.         } c;
  41.     } u;
  42. };
  43.  
  44. #define    l_line    l_n
  45. #define    l_pad    l_n
  46. #define    l_lab    u.l.l_l
  47. #define l_val    u.l.l_v
  48. #define l_valid    u.l.l_va
  49. #define l_op    u.i.l_i
  50. #define l_sz    u.i.l_s
  51. #define    l_cp    u.c.l_c
  52. #define    l_const    u.c.l_con
  53. #define    l_len    u.c.l_con
  54. #define    l_str    u.c.l_s
  55.  
  56.  
  57. struct link *lh;    /* head of linked-list of labels */
  58. struct link *lt;    /* tail of linked-list of labels */
  59. struct link *ih;    /* head of linked-list of instructions */
  60. struct link *it;    /* tail of linked-list of instructions */
  61. struct link *ch;    /* head of linked-list of constants */
  62. struct link *ct;    /* tail of linked-list of constants */
  63.  
  64. struct link *get_lab_in();
  65. struct link *smalloc();
  66.  
  67. int bcnt = LOADADR;    /* output byte count */
  68. int svin = -1;        /* saved index of label to be defined */
  69.  
  70. extern int lineno;
  71.  
  72.  
  73. /* set up linked lists */
  74. init_links()
  75. {
  76.     lh = smalloc(sizeof(struct link));
  77.     ih = smalloc(sizeof(struct link));
  78.  
  79.     lh->l_next = lh;
  80.     lt = lh;
  81.     ih->l_next = ih;
  82.     it = ih;
  83.     ch = 0;
  84.     ct = 0;
  85. }
  86.  
  87.  
  88. /* add label to list if needed, return index */
  89. int
  90. add_lab(lab)
  91. char *lab;
  92. {
  93.     register struct link *l;
  94.     register int i;
  95.  
  96.     for(i = 0, l = lh->l_next; l != lh; i++, l = l->l_next)
  97.         if(!strcmp(lab, l->l_lab))
  98.             return i;
  99.  
  100.     l = smalloc(sizeof(struct link));
  101.     l->l_next = lh;
  102.     lt->l_next = l;
  103.     lt = l;
  104.  
  105.     l->l_lab = (char *)smalloc(strlen(lab)+1);
  106.     strcpy(l->l_lab, lab);
  107.     l->l_val = 0;
  108.     l->l_valid = 0;
  109.  
  110.     return i;
  111. }
  112.  
  113.  
  114. /* assign value to label by index */
  115. add_val(in, val)
  116. int in, val;
  117. {
  118.     register int i;
  119.     register struct link *l;
  120.  
  121.     for(i = 0, l = lh->l_next; i < in; i++)
  122.         l = l->l_next;
  123.  
  124.     if(l->l_valid) {
  125.         lineno--;
  126.         yyerror("label multiply defined");
  127.         lineno++;
  128.     }
  129.     else {
  130.         l->l_valid = 1;
  131.         l->l_val = val;
  132.     }
  133. }
  134.  
  135.  
  136. /* get label by index */ 
  137. struct link *
  138. get_lab_in(in)
  139. register int in;
  140. {
  141.     register struct link *l;
  142.  
  143.     for(l = lh->l_next; in; in--)
  144.         l = l->l_next;
  145.  
  146.     return l;
  147. }
  148.  
  149.  
  150. /* check the size of the potential binary */
  151. chk_size()
  152. {
  153.     if(--bcnt > MAXADDR) {
  154.         printf("Error - program too large for address space ");
  155.         printf("(0x%X > 0x%3X)\n", bcnt, MAXADDR);
  156.         return 1;
  157.     }
  158.  
  159.     return 0;
  160. }
  161.  
  162.  
  163. /* check the linked list of labels for any that are undefined */
  164. chk_lab()
  165. {
  166.     static int first = 1;
  167.     register struct link *l;
  168.  
  169.     for(l = lh->l_next; l != lh; l = l->l_next)
  170.         if(!l->l_valid) {
  171.             if(first) {
  172.                 printf("Error - undefined labels:\n");
  173.                 first = 0;
  174.             }
  175.             printf("\t%s\n", l->l_lab);
  176.         }
  177.  
  178.     return(!first);
  179. }
  180.  
  181.  
  182. /* check the value of constants to make sure they are in bounds */
  183. chk_val()
  184. {
  185.     register struct link *l, *lp;
  186.     register int x;
  187.     struct link *lp2;
  188.     int i, y, err = 0;
  189.  
  190.     for(l = ih->l_next; l != ih; l = l->l_next)
  191.         switch(l->l_type) {
  192.             case T_CON:
  193.             for(lp = l->l_cp; lp; lp = lp->l_cp) {
  194.                 x = lp->l_const;
  195.                 if(x > 0xFFF) {
  196.                     lp2 = get_lab_in((x >> 12)-1);
  197.                     x = lp2->l_const;
  198.                 }
  199.                     
  200.                 if(x > 0xFF) {
  201.                     print_ctl(lp->l_line, !err);
  202.                     err = 1;
  203.                     break;
  204.                 }
  205.             }
  206.             break;
  207.  
  208.             case T_INST:
  209.             for(i = 0; i < 3; i++) {
  210.                 if(l->l_op[i+1] > 0xFFF) {
  211.                     lp = get_lab_in((l->l_op[i+1] >> 12)-1);
  212.                     x = lp->l_val;
  213.                 }
  214.                 else
  215.                     x = l->l_op[i+1];
  216.  
  217.                 y = l->l_sz[i];
  218.                 if(y < 0)
  219.                     y++;
  220.  
  221.                 if(x >= (1 << (y * 4))) {
  222.                     print_ctl(l->l_line, !err);
  223.                     err = 1;
  224.                     break;
  225.                 }
  226.             }
  227.             break;
  228.  
  229.             default:
  230.             break;
  231.         }
  232.  
  233.     return err;
  234. }
  235.  
  236.  
  237. /* check to see if the last instruction is a label */
  238. chk_var()
  239. {
  240.     if(svin != -1)
  241.         add_val(svin, bcnt);
  242. }
  243.  
  244.  
  245. /* add instruction to list */
  246. add_inst(line, a0, a1, s1, a2, s2, a3, s3)
  247. int line, a0, a1, s1, a2, s2, a3, s3;
  248. {
  249.     register struct link *l;
  250.  
  251.     ct = ch;
  252.  
  253.     if(svin != -1) {
  254.         add_val(svin, bcnt + (bcnt % 2));
  255.         svin = -1;
  256.     }
  257.  
  258.     if(bcnt % 2)
  259.         add_pad(1);
  260.  
  261.     l = smalloc(sizeof(struct link));
  262.     l->l_line = line;
  263.     l->l_type = T_INST;
  264.  
  265.     l->l_op[0] = a0;
  266.     l->l_op[1] = a1;
  267.     l->l_op[2] = a2;
  268.     l->l_op[3] = a3;
  269.  
  270.     l->l_sz[0] = s1;
  271.     l->l_sz[1] = s2;
  272.     l->l_sz[2] = s3;
  273.  
  274.     l->l_next = ih;
  275.     it->l_next = l;
  276.     it = l;
  277.  
  278.     bcnt += 2;
  279. }
  280.  
  281.  
  282. /* add constant to string list */
  283. add_con(line, c)
  284. int line, c;
  285. {
  286.     if(!ch) {
  287.         ch = smalloc(sizeof(struct link));
  288.         ch->l_cp = 0;
  289.         ct = ch;
  290.     }
  291.  
  292.     if(!ct->l_cp) {
  293.         ct->l_cp = smalloc(sizeof(struct link));
  294.         ct = ct->l_cp;
  295.         ct->l_cp = 0;
  296.     }
  297.     else
  298.         ct = ct->l_cp;
  299.  
  300.     ct->l_type = T_CON;
  301.     ct->l_line = line;
  302.     ct->l_const = c;
  303. }
  304.  
  305.  
  306. /* add a string to linked list of constants */
  307. add_str(line, s)
  308. int line;
  309. char *s;
  310. {
  311.     int i;
  312.  
  313.     if(!ch) {
  314.         ch = smalloc(sizeof(struct link));
  315.         ch->l_cp = 0;
  316.         ct = ch;
  317.     }
  318.  
  319.     if(!ct->l_cp) {
  320.         ct->l_cp = smalloc(sizeof(struct link));
  321.         ct = ct->l_cp;
  322.         ct->l_cp = 0;
  323.     }
  324.     else
  325.         ct = ct->l_cp;
  326.  
  327.     i = strlen(s);
  328.     ct->l_len = i;
  329.     ct->l_str = (unsigned char *)smalloc(++i);
  330.     strcpy(ct->l_str, s);
  331.  
  332.     ct->l_type = T_STR;
  333.     ct->l_line = line;
  334. }
  335.  
  336.  
  337. /* add a byte pad directive to the linked list of instructions */
  338. add_pad(n)
  339. int n;
  340. {
  341.     register struct link *l;
  342.  
  343.     if(svin != -1) {
  344.         add_val(svin, bcnt);
  345.         svin = -1;
  346.     }
  347.  
  348.     if(n > 0xFFF) {
  349.         n = n >> 12;
  350.         l = get_lab_in(--n);
  351.         if(!l->l_valid) {
  352.             yyerror("constant must be forward declared");
  353.             n = 0;
  354.         }
  355.         else
  356.             n = l->l_val;
  357.     }
  358.  
  359.     bcnt += n;
  360.     ct = ch;
  361.  
  362.     l = smalloc(sizeof(struct link));
  363.     l->l_type = T_PAD;
  364.     l->l_pad = n;
  365.     l->l_next = ih;
  366.     it->l_next = l;
  367.     it = l;
  368. }
  369.  
  370.  
  371. /* add a constant list directive to the linked list of instructions */
  372. add_str_list()
  373. {
  374.     register struct link *l;
  375.     register int i;
  376.  
  377.     if(ch == ct)
  378.         return;
  379.  
  380.     if(svin != -1) {
  381.         add_val(svin, bcnt);
  382.         svin = -1;
  383.     }
  384.  
  385.     for(l = ch->l_cp, i = 0; l; l = l->l_cp)
  386.         if(l->l_type == T_STR)
  387.             i += l->l_len;
  388.         else
  389.             i++;
  390.  
  391.     bcnt += i;
  392.  
  393.     ch->l_type = T_CON;
  394.     ch->l_next = ih;
  395.     it->l_next = ch;
  396.     it = ch;
  397.     ch = ct->l_cp;
  398.     ct->l_cp = 0;
  399.     ct = ch;
  400. }
  401.  
  402.  
  403. /* output instructions accordingly */
  404. out_inst(fp, asc)
  405. FILE *fp;
  406. int asc;
  407. {
  408.     register struct link *l, *lp, *lp2;
  409.     register int y;
  410.     int i, x;
  411.     unsigned char c, *p;
  412.  
  413.     for(l = ih->l_next; l != ih; l = l->l_next)
  414.         switch(l->l_type) {
  415.             case T_CON:
  416.             for(lp = l->l_cp; lp; lp = lp->l_cp) {
  417.                 if(lp->l_type == T_STR) {
  418.                     p = lp->l_str;
  419.                     while(*p) {
  420.                         if(asc) {
  421.                             if(fprintf(fp, "%.2X",
  422.                                 *p) != 2)
  423.                                 return 0;
  424.                         }
  425.                         else
  426.                             if(fwrite(p, 1, 1, fp)
  427.                                 != 1)
  428.                                 return 0;
  429.                         p++;
  430.                     }
  431.                 }
  432.                 else {
  433.                     y = lp->l_const;
  434.                     if(y > 0xFFF) {
  435.                         y = y >> 12;
  436.                         lp2 = get_lab_in(--y);
  437.                         y = lp2->l_val;
  438.                     }
  439.  
  440.                     if(asc) {
  441.                         if(fprintf(fp, "%.2X", y) != 2)
  442.                             return 0;
  443.                     }
  444.                     else {
  445.                         c = y;
  446.                         if(fwrite(&c, 1, 1, fp) != 1)
  447.                             return 0;
  448.                     }
  449.                 }
  450.             }
  451.             break;
  452.  
  453.             case T_INST:
  454.             x = l->l_op[0] << 12;
  455.  
  456.             for(i = 1; i < 4; i++) {
  457.                 y = l->l_op[i];
  458.                 if(y > 0xFFF) {
  459.                     y = y >> 12;
  460.                     lp = get_lab_in(--y);
  461.                     y = lp->l_val;
  462.                 }
  463.                 x |= y << (12 - (i * 4));
  464.             }
  465.  
  466.             if(asc) {
  467.                 if(fprintf(fp, "%.4X", x) != 4)
  468.                     return 0;
  469.             }
  470.             else {
  471.                 c = x >> 8;
  472.                 if(fwrite(&c, 1, 1, fp) != 1)
  473.                     return 0;
  474.                 c = x & 0xFF;
  475.                 if(fwrite(&c, 1, 1, fp) != 1)
  476.                     return 0;
  477.             }
  478.             break;
  479.  
  480.             case T_PAD:
  481.             for(i = 0; i < l->l_pad; i++)
  482.                 if(asc) {
  483.                     if(fprintf(fp, "%.2X", 0) != 2)
  484.                         return 0;
  485.                 }
  486.                 else {
  487.                     c = 0;
  488.                     if(fwrite(&c, 1, 1, fp) != 1)
  489.                         return 0;
  490.                 }
  491.             break;
  492.         }
  493.  
  494.     return 1;
  495. }
  496.  
  497.  
  498. /* print constant size error list */
  499. print_ctl(line, first)
  500. int line, first;
  501. {
  502.     if(first)
  503.         printf("Error - constant size:\n");
  504.  
  505.     printf("\tline %d\n", line);
  506. }
  507.  
  508.  
  509. /* "safe" malloc */
  510. struct link *
  511. smalloc(size)
  512. int size;
  513. {
  514.     struct link *p;
  515.  
  516.     if(!(p = (struct link *)malloc(size))) {
  517.         perror("malloc");
  518.         exit(1);
  519.     }
  520.  
  521.     return p;
  522. }
  523.